package wpp;

import org.apache.log4j.Logger;

import wpp.cfg.DataConfig;
import wpp.fxservice.WPStopImageHunterService;
import wpp.view.FavorPreviewPane;
import wpp.view.LocalPreviewPane;
import wpp.view.MainButtonSet;

import javafx.application.Application;
import javafx.beans.property.ReadOnlyDoubleProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.WorkerStateEvent;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.ProgressBar;
import javafx.scene.effect.GaussianBlur;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class WPP extends Application {
	
	private static final Logger LOGGER = Logger.getLogger(WPP.class);

	private static StackPane rootPane;
	private static BorderPane contentPane;
	private static Node currentShowContent;
	
	private static LocalPreviewPane localPreviewPane;	
	private static FavorPreviewPane favorPane;
	
	private static Pane contentBlurLayer;
	private static GaussianBlur contentBlurEffect;
	private static ProgressBar contentProgressBar;	
	
	public static void main(String[] args) {
		launch(args);
	}
				
	@Override
	public void start(Stage stage) throws Exception {	
		LOGGER.info("WPP started");
		WPPConfig.initWPPConfig();
		downloadImages();
		init(stage);
		stage.show();	
	}	

	@Override
	public void stop() throws Exception {	
		DataConfig.save();
		LOGGER.info("WPP stoped");
	}		

	private void init(Stage stage) {
		rootPane = new StackPane();
		contentPane = new BorderPane();	
		contentPane.setTop(new MainButtonSet());
		localPreviewPane = new LocalPreviewPane();
		favorPane = new FavorPreviewPane();
		refreshMainContent(localPreviewPane);
		rootPane.getChildren().add(contentPane);
		Scene scene = new Scene(rootPane, WPPConfig.getAppWidth(), WPPConfig.getAppHeight());	
		scene.getStylesheets().addAll(WPPConfig.getThemeCSSPath(), WPPConfig.getMainCSSPath());
		stage.setTitle(WPPConfig.getAppTitle());
		stage.setResizable(false);
		stage.setScene(scene);
	}
	
	public static void showLocalPreviewPane() {
		if(currentShowContent != localPreviewPane) {
			refreshMainContent(localPreviewPane);
		}
	}
	
	public static void showFavorPane() {
		if(currentShowContent != favorPane) {	
			favorPane.cleanImages();
			refreshMainContent(favorPane);
			favorPane.loadImages();
		}		
	}
	
	public static void contentBlur() {
		if(contentBlurLayer == null) {
			contentBlurLayer = new Pane();
			contentBlurLayer.getStyleClass().add("content-blur-layer");
			contentBlurEffect = new GaussianBlur();
			contentPane.setEffect(contentBlurEffect);			
		}
		contentBlurEffect.setRadius(20);
		rootPane.getChildren().add(contentBlurLayer);
	}		
	
	public static void contentFocus() {
		if(contentBlurLayer != null) {
			contentBlurEffect.setRadius(0);
			rootPane.getChildren().remove(contentBlurLayer);
		}
	}
	
	public static void showProgressBar(ReadOnlyDoubleProperty progressProperty) {
		contentBlur();
		if(contentProgressBar == null) {
			contentProgressBar = new ProgressBar();
			contentProgressBar.setPrefSize(350, 20);
		}
		contentProgressBar.progressProperty().unbind();
		contentProgressBar.progressProperty().bind(progressProperty);
		rootPane.getChildren().add(contentProgressBar);			
	}
	
	public static void clearProgressBar() {
		contentFocus();
		if(contentProgressBar != null) {
			rootPane.getChildren().removeAll(contentProgressBar);			
		}
	}
	
	private static void refreshMainContent(Node content) {
		currentShowContent = content;
		contentPane.setCenter(currentShowContent);	
	}
	
	private void downloadImages() {
		final WPStopImageHunterService imageHunterService = new WPStopImageHunterService();
		final ChangeListener<Number> listener = new ChangeListener<Number>() {
			@Override
			public void changed(ObservableValue<? extends Number> observable,
					Number oldValue, Number newValue) {
				afterNewWPPreviewDownload();				
			}			
		};
		imageHunterService.progressProperty().addListener(listener);
		EventHandler<WorkerStateEvent> cleanLiStateEvent = new EventHandler<WorkerStateEvent>() {
			@Override
			public void handle(WorkerStateEvent arg0) {
				imageHunterService.progressProperty().removeListener(listener);
			}
		};
		imageHunterService.setOnSucceeded(cleanLiStateEvent);
		imageHunterService.setOnCancelled(cleanLiStateEvent);
		imageHunterService.setOnFailed(cleanLiStateEvent);		
		imageHunterService.start();
	}
	
	private void afterNewWPPreviewDownload() {
		localPreviewPane.addANewWPPreview();
	}
}
